#!/bin/bash
#
#  Copyright (c) 2021, The OpenThread Authors.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#  3. Neither the name of the copyright holder nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
#

# Keep folder information
if [[ -n ${BASH_SOURCE[0]} ]]; then
    script_path="${BASH_SOURCE[0]}"
else
    script_path="$0"
fi

script_dir="$(dirname "$(realpath "$script_path")")"
repo_dir="$(dirname "$script_dir")"

source "$script_dir"/common_utility

print_usage()
{
    echo "Usage: $0 [-h] [-v] -p <serial port> -b <board> -d <device type> -a <target application>"
    echo "       -h : help"
    echo "       -v : verbose"
    echo "       -p : target serial port"
    echo "       -b : target board"
    echo "       -d : target device type, this field is invalid if target application is set to rcp"
    echo "            Currently, target device type could be ftd or mtd"
    echo "       -a : target application"
    echo "            Currently, target application could be cli, ncp, or rcp"
}

main()
{
    # Parse input parameters
    while getopts "p:b:d:a:hv" optchar; do
        case "${optchar}" in
            p)
                local PORT="${OPTARG}"
                ;;
            b)
                local BOARD="${OPTARG}"
                echo "BOARD: $BOARD"
                ;;
            d)
                local TARGET="${OPTARG}"
                echo "TARGET: $TARGET"
                ;;
            v)
                local VERBOSE=--verbose
                ;;
            a)
                local APP="${OPTARG}"
                ;;
            *)
                print_usage
                exit 2
                ;;
        esac
    done
    shift $((OPTIND - 1))

    # Check parameters
    if [ ! -v PORT ] || [ ! -v BOARD ] || [ ! -v APP ]; then
        print_usage
        exit 2
    fi

    if [ "$APP" != "rcp" ]; then
        if [ ! -v TARGET ]; then
            print_usage
            exit 2
        fi
    fi

    # Find available platforms
    declare -a ifx_platform=()
    platform_dir="$(pwd)"/third_party/infineon/platform
    available_platforms_load ifx_platform "$platform_dir"

    # Find target platform
    local target_platform=''
    local platform_found=0
    for target_platform in "${ifx_platform[@]}"; do
        if [[ $BOARD == *"$target_platform"* ]]; then
            platform_found=1
            break
        fi
    done

    if [[ ${platform_found} == 0 ]]; then
        # special case handling
        # Use a loop to iterate through each character in the string
        for ((i = 0; i < ${#BOARD}; i++)); do
            char=${BOARD:i:1} # Get the character at index i

            # Check if the character is a number
            if [[ $char =~ ^[0-9]$ ]]; then
                break
            fi
        done

        local platform_leading_substring=${BOARD:0:i}

        # Find target platform with the same leading substring
        for target_platform in "${ifx_platform[@]}"; do
            if [[ $platform_leading_substring == "${target_platform:0:i}" ]]; then
                if [[ $BOARD == *"${target_platform:i}"* ]]; then
                    platform_found=1
                    break
                fi
            fi
        done
    fi

    if [[ ${platform_found} == 0 ]]; then
        exit 1
    fi

    echo "Target Platform: $target_platform"

    # Set target script path
    local IFX_SCRIPTS_DIR="$repo_dir/third_party/infineon/platform/$target_platform/scripts"

    echo "IFX_SCRIPTS_DIR: $IFX_SCRIPTS_DIR"

    local SDK_TOOLS_DIR=third_party/infineon/btsdk-tools

    local IFX_MTB_TOOLS_DIR=
    for dir in {${USERPROFILE:-${HOME}},/Applications}/ModusToolbox/tools_*; do
        if [ -d "${dir}" ]; then
            IFX_MTB_TOOLS_DIR="${dir}"
            break
        fi
    done

    if [[ $OSTYPE == "linux-gnu"* ]]; then
        local SDK_TOOLS_SUB_DIR=Linux64
    elif [[ $OSTYPE == "darwin"* ]]; then
        local SDK_TOOLS_SUB_DIR=OSX
    else
        local SDK_TOOLS_SUB_DIR=Windows
    fi

    set +u

    if [ "$APP" == "rcp" ]; then
        local TARGET_APP_DIR="${OT_BUILDDIR}/${BOARD}/${APP}/bin"
    else
        local TARGET_APP_DIR="${OT_BUILDDIR}/${BOARD}/${APP}/bin/${TARGET}"
    fi

    bash --norc --noprofile \
        "${IFX_SCRIPTS_DIR}/bt_program.bash" \
        --shell="${IFX_MTB_TOOLS_DIR}/modus-shell" \
        --tools="${SDK_TOOLS_DIR}/${SDK_TOOLS_SUB_DIR}" \
        --scripts="${IFX_SCRIPTS_DIR}" \
        --hex="${TARGET_APP_DIR}/${APP}_download.hex" \
        --elf="${TARGET_APP_DIR}/${APP}.elf" \
        --uart="${PORT}" \
        --direct=0 \
        ${VERBOSE-}

    set -u
}

###################################################################################################
#
# Program Start
#
###################################################################################################

set -euo pipefail

if [[ $OSTYPE == "cygwin" ]]; then
    OT_BUILDDIR=$(cygpath -m "${OT_CMAKE_BUILD_DIR:-$repo_dir/build}")
    readonly OT_BUILDDIR
else
    OT_BUILDDIR="${OT_CMAKE_BUILD_DIR:-$repo_dir/build}"
    readonly OT_BUILDDIR
fi

main "$@"
